#include "MonteCarloUtility.h"
#include "Utility.h"
#include "GlobalDefine.h"


mray::vec3 mray::UniformSampleHemisphere(float u1, float u2)
{
	float z = u1;
	float r = sqrt(Max(0.f, 1.f-z*z));
	float phi = 2 * PI * u2;
	float x = r * cos(phi);
	float y = r * sin(phi);
	return vec3(x,y,z);
}

float mray::UniformHemispherePdf()
{
	return INV_TWOPI;
}

mray::vec2 mray::CentricSampleDisk(float u1, float u2)
{
	float r, theta;
	//map uniform random number to [-1,1]
	float sx = u1*2.f-1.f;
	float sy = u2*2.f-1.f;
	//map square to (r, theta)
	if(sx >= -sy)
		if(sx > sy){
			r = sx;
			theta = sy/sx;
		}else{
			r = sy;
			theta = 2.f - sx/sy;
		}
	else
		if(sx <= sy){
			r = -sx;
			theta = sy/sx + 4.f;
		}
		else{
			r = -sy;
			theta = -2.f - sx/sy;
		}
		theta *= PI/4.f;
		//return result
		float dx = r * cos(theta);
		float dy = r * sin(theta);
		return vec2(dx, dy);
}

mray::vec3 mray::CosineSampleHemisphere(float u1, float u2)
{
	vec2 tmp = CentricSampleDisk(u1, u2);
	return vec3(
		tmp.x, 
		tmp.y, 
		sqrt(Max(0.f, 1.f-tmp.x*tmp.x-tmp.y*tmp.y))
		);
}

float mray::CosineHemispherePdf(float costheta, float phi)
{
	return costheta * INV_PI;
}
